package com;

import groups.groups;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

import misc.utility;

import strings.strings;

import database.databaseInteraction;
import database.database_auth;
import database.user;

public class communication {
	/** strategy is like this:
	 * write one record into table communication for every message.
	 * 
	 * if the message goes to multiple users (group), write one record (with same message text) for every user.
	 * if the message goes to a discussion, check out what USERIDs have subscribed to this discussion and then write
	 * one record for every user that has subscribed to this discussion.
	 * 
	 * this way SELECT statements are very fast and filtering can be handled mainly by the MySQL database,
	 * speeding up read operations,
	 * 
	 * but yes there is some redundant information saved when the exactly same message gets written to database
	 * for every user.
	 */
	
	public groups groups_inst = new groups();
	public user user_inst = new user();
	public strings strings_inst = new strings();
	public utility utility_inst = new utility();
	
	String question = "";
	
	String status = ""; // any error/success messages that occurs during operation
	Boolean result = null; // any error/success messages that occurs during operation
	
	databaseInteraction DatabaseConnection = new databaseInteraction();
	
	Pattern delimiter_semicolon = Pattern.compile(";");
	
	/** checks various tables for new messages for the user:
	 * 
	 * strategy: get all messages for this user than filter out.
	 * 
	 * 1. USERID in the list of receivers? (receiverUser)
	 * 2. does USERID belong to receiverGroup?
	 * 3. has USERID subscribed to the discussionID? 
	 * 
	 * filter out:
	 * 1. is user ignoring the source of the message? (spammer?)
	 * 2. has message status "deleted" for this USERID?
	 * @param USERID
	 * @return
	 */
	public HashMap getMessagesForUSERID(String USERID)
	{
		HashMap messages = new HashMap();
		return messages;
	}
	
	/** send message to a a User/Group/Discussion/Project
	 * there are thwo possible ways of creating a message delivery system
	 * 1. no real group-messages exist, when a message is delivered to a group, it is actually send to all members of that group.
	 * in short: this approach suckx, because redundant data is stored (the actual message)
	 * when deleting the message it needs to be deleted multiple times.
	 * if it is altered the message needs to be altered multiple times.
	 * 
	 * 2. real group-messages exist: the message is not send to individual users but to a groupID
	 * and on polling it needs to be checked in what groups the user resides and then get all messages for that group
	 * that the user has not yet read.
	 * 
	 * this is putting more stress on the server while polling, if not the client is transmitting 
	 * what groups should be checked.
	 * **/
	public boolean sendMessage(message MESSAGE_inst, database_auth database_auth_inst)
	{
		boolean result = true;
	
		// 1.4. split user1;user2;user3;
		// String[] toUserIDs = delimiter_semicolon.split(MESSAGE_inst.toUserID); // makes things too complicated, KEEP IT SIMPLE!
		// 1.5. send message to users
		//			for(Integer counter=0; counter<toUserIDs.length; counter++)
		//			{
		//				toUserIDs[counter]
		//			}

		if(!MESSAGE_inst.toUserID.equals(""))
		{
			// check if toUserID is ignoring fromUserID
			if(user_inst.ignored(MESSAGE_inst.fromUserID, MESSAGE_inst.toUserID, database_auth_inst) == false)
			{
				// send message to user
				String question = "INSERT INTO `together`.`communication` "+
				"(`ID`,`MESSAGEID`                 ,`subject`                  ,`toDiscussionID`,`discussionParentID`,`fromUserID`,                  `toUserID`,                 `toGroupID`,  `toProjectID`,               `timeSend`,                  `status`,                  `text`,  `spam`) "+
				"VALUES" +
				"(NULL,'"+MESSAGE_inst.MESSAGEID+"', '"+MESSAGE_inst.subject+"','0'             ,'0'                 ,'"+MESSAGE_inst.fromUserID+"', '"+MESSAGE_inst.toUserID+"','"+MESSAGE_inst.toGroupID+"','0',         '"+MESSAGE_inst.timeSend+"', '"+MESSAGE_inst.status+"', '"+MESSAGE_inst.message+"','0');";

				DatabaseConnection.askDatabase(database_auth_inst, question); // StringBuffer answer = DatabaseConnection.askDatabase( host, DatabaseName, TableName, user, password, question);
				result = DatabaseConnection.success;
				status = DatabaseConnection.status;
			}
		}
		if(!MESSAGE_inst.toGroupID.equals(""))
		{
			// not implemeted yet: check if user is blocked by this group
			// send message to user
			String question = "INSERT INTO `together`.`communication` "+
			       "(`ID`,                 `MESSAGEID`,                 `subject`  ,`toDiscussionID`,`discussionParentID`,               `fromUserID` ,`toUserID`,`toGroupID`                 ,`toProjectID`,`timeSend`                 ,`status`                  ,`text`                  ,`spam`) "+
			"VALUES (NULL, '"+MESSAGE_inst.MESSAGEID+"', '"+MESSAGE_inst.subject+"', '0'           ,'0'                ,'"+MESSAGE_inst.fromUserID+"', '0'     ,'"+MESSAGE_inst.toGroupID+"','0'         ,'"+MESSAGE_inst.timeSend+"', '"+MESSAGE_inst.status+"', '"+MESSAGE_inst.message+"','0');";

			DatabaseConnection.askDatabase(database_auth_inst, question); // StringBuffer answer = DatabaseConnection.askDatabase( host, DatabaseName, TableName, user, password, question);
			result = DatabaseConnection.success;
			status = DatabaseConnection.status;
		}
		if(!MESSAGE_inst.toDiscussionID.equals(""))
		{
			// send message to discussion
			String question = "INSERT INTO `together`.`communication` "+
			       "(`ID`,                  `MESSAGEID`,                `subject`  ,`toDiscussionID`                  ,`discussionParentID`,               `fromUserID` ,`toUserID`,`toGroupID`,`toProjectID`,`timeSend`                 ,`status`                  ,`text`                  ,`spam`) "+
			"VALUES (NULL, '"+MESSAGE_inst.MESSAGEID+"', '"+MESSAGE_inst.subject+"','"+MESSAGE_inst.toDiscussionID+"1','0'                ,'"+MESSAGE_inst.fromUserID+"', '0'     ,'0'       ,'0'         ,'"+MESSAGE_inst.timeSend+"', '"+MESSAGE_inst.status+"', '"+MESSAGE_inst.message+"','0');";

			DatabaseConnection.askDatabase(database_auth_inst, question); // StringBuffer answer = DatabaseConnection.askDatabase( host, DatabaseName, TableName, user, password, question);
			result = DatabaseConnection.success;
			status = DatabaseConnection.status;
		}
		if(!MESSAGE_inst.toProjectID.equals(""))
		{
			//  send message to project
			String question = "INSERT INTO `together`.`communication` "+
			       "(`ID`,                  `MESSAGEID`,                `subject`  ,`toDiscussionID`,`discussionParentID`,               `fromUserID` ,`toUserID`,`toGroupID`,`toProjectID`                 ,`timeSend`                 ,`status`                  ,`text`                  ,`spam`) "+
			"VALUES (NULL, '"+MESSAGE_inst.MESSAGEID+"', '"+MESSAGE_inst.subject+"','0'            ,'0'                ,'"+MESSAGE_inst.fromUserID+"', '0'     ,'0'       ,'"+MESSAGE_inst.toProjectID+"','"+MESSAGE_inst.timeSend+"', '"+MESSAGE_inst.status+"', '"+MESSAGE_inst.message+"','0');";

			DatabaseConnection.askDatabase(database_auth_inst, question); // StringBuffer answer = DatabaseConnection.askDatabase( host, DatabaseName, TableName, user, password, question);
			result = DatabaseConnection.success;
			status = DatabaseConnection.status;

		}
		
		return result;
	}
	
	/** add ChatMessage to a chat-session
	 * 1. check if such session exists
	 * if yes:
	 * 2.1. add chat message to existing chat messages
	 * if no:
	 * 2.2. create a new record
	 * 
	 * 3. count and return the amount of #-separated chat-messages in the record
	 * **/
	public StringBuffer sendChatMessage(chatSession CHATSESSION_inst, database_auth database_auth_inst)
	{
		int ChatMessageCount = 0;
		
		StringBuffer answer = new StringBuffer();
		// Map<String,String> RESULT = new HashMap<String,String>(); 
		
		if(!utility_inst.empty(CHATSESSION_inst.ChatSessionID))
		{
			// check if toUserID is ignoring fromUserID
			if(user_inst.ignored(CHATSESSION_inst.getfromUserID(), CHATSESSION_inst.gettoUserID(), database_auth_inst) == false)
			{
				// * 1. check if such session exists
				String question = "SELECT * FROM `together`.`chat` WHERE `ChatSessionID` = '"+CHATSESSION_inst.ChatSessionID+"'";
				DatabaseConnection.askDatabase(database_auth_inst, question); // StringBuffer answer = DatabaseConnection.askDatabase( host, DatabaseName, TableName, user, password, question);
				
			    int LENGTH = DatabaseConnection.answerJAVA.size();
			    if(LENGTH > 0)
			    {
			    	// * if yes:
			    	// * 2.1. add chat message to existing chat messages
				    for(int counter = 0;counter < LENGTH;counter++)
				    {
				    	HashMap element = (HashMap) DatabaseConnection.answerJAVA.get(counter);
				    	
				    	CHATSESSION_inst.text = CHATSESSION_inst.text + element.get("text");
				    	ChatMessageCount = strings_inst.countChar(CHATSESSION_inst.text, "#");
				    	
				    	CHATSESSION_inst.ChatMessageCount = Integer.toString(ChatMessageCount);

				    	// also update ChatMessageCount
				    	question = "UPDATE `together`.`chat` SET `text` = '"+CHATSESSION_inst.text+"',`ChatMessageCount` = '"+CHATSESSION_inst.ChatMessageCount+"' WHERE `chat`.`ChatSessionID` = '"+CHATSESSION_inst.ChatSessionID+"';";
						DatabaseConnection.askDatabase(database_auth_inst, question);
						result = DatabaseConnection.success;
						status = DatabaseConnection.status;
				    }
			    }
			    else
			    {
				    // * if no:
				    // * 2.2. create a new record
			    	
			    	question = "INSERT INTO `together`.`chat` (`ID`,`ChatSessionID`                     ,`subject`                      ,`toDiscussionID`,`discussionParentID`,`fromUserID`                          ,`toUserID`                           ,`toGroupID`,`toProjectID`,`status`                     ,`text`                      ,`spam`,`TimeStarted`                     ,`TimeFinished`                     ,`TimeLastMessage`                     ,`ChatMessageCount`                     , `Priority`)"
			    			                        + "VALUES (NULL,'"+CHATSESSION_inst.ChatSessionID+"', '"+CHATSESSION_inst.subject+"','0'             ,'0'                 ,'"+CHATSESSION_inst.getfromUserID()+"', '"+CHATSESSION_inst.gettoUserID()+"','0'        ,'0'          ,'"+CHATSESSION_inst.status+"', '"+CHATSESSION_inst.text+"','0'   ,'"+CHATSESSION_inst.TimeStarted+"','"+CHATSESSION_inst.TimeFinished+"','"+CHATSESSION_inst.TimeLastMessage+"','"+CHATSESSION_inst.ChatMessageCount+"','"+CHATSESSION_inst.Priority+"');";

			    	DatabaseConnection.askDatabase(database_auth_inst, question); // StringBuffer answer = DatabaseConnection.askDatabase( host, DatabaseName, TableName, user, password, question);
			    	result = DatabaseConnection.success;
			    	status = DatabaseConnection.status;
				}

				// * 3. count and return the amount of #-separated chat-messages in the record
			}
		}

		String question = "SELECT * FROM `together`.`chat` WHERE `ChatSessionID` = '"+CHATSESSION_inst.ChatSessionID+"'";
		answer.append(DatabaseConnection.askDatabase(database_auth_inst, question)); // StringBuffer answer = DatabaseConnection.askDatabase( host, DatabaseName, TableName, user, password, question);
		result = DatabaseConnection.success;
		status = DatabaseConnection.status;

		return answer;
	}

	/**
	 * check what is the MESSAGECOUNT 
	 * MessageIDs identify a message (to multiple users = multiple records, but only 1x MessageID)
	 */
	public int getMessageCount(database_auth database_auth_inst)
	{
		int MESSAGECOUNT = 0;
		
		DatabaseConnection.askDatabase(database_auth_inst, "SELECT MESSAGECOUNT FROM `system`;");
		
		/** iterate over ArrayList answerJava and check if UNIQUE_MESSAGEID is really not used yet **/
		int LENGTH = DatabaseConnection.answerJAVA.size();
		for(int counter = 0;counter < LENGTH;counter++)
		{
			HashMap element = (HashMap) DatabaseConnection.answerJAVA.get(counter);
			MESSAGECOUNT = Integer.valueOf((String) element.get("MESSAGECOUNT"));
		}
		
		return MESSAGECOUNT;
	}
	
	/**
	 * update a property of a message
	 */
	public boolean updateMessage(String MessageID,String key, String value, database_auth database_auth_inst)
	{
		String question = "UPDATE `together`.`communication` SET `"+key+"` = '"+value+"' WHERE `communication`.`ID` = "+MessageID+";";
		DatabaseConnection.askDatabase(database_auth_inst, question);
		
		return DatabaseConnection.success;
	}
	
	/**
	 * set new value for MESSAGECOUNT 
	 * MessageIDs identify a message (to multiple users = multiple records, but only 1x MessageID)
	 */
	public void setMessageCount(int NEWMESSAGECOUNT, database_auth database_auth_inst)
	{
		DatabaseConnection.askDatabase(database_auth_inst, "UPDATE `together`.`system` SET `MESSAGECOUNT` = '"+NEWMESSAGECOUNT+"' WHERE `system`.`ID` = 1;");
	}
}
